﻿#include "gplayer.h"
#include "./ui_gplayer.h"

#include "songinfo.h"
#include "option.h"

#include <QDebug>
#include <QMessageBox>
#include <QCloseEvent>
#include <QMouseEvent>
#include <QFileDialog>

#include <QTime>

void sleep(int msec)
{
    QTime reachTime = QTime::currentTime().addMSecs(msec);

    while(QTime::currentTime() < reachTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

static QString Time(qint64 time)//转换时间
{
    qint64 seconds=time/1000;
    const qint64 minutes=seconds/60;
    seconds-=minutes*60;
    return QStringLiteral("%1:%2")
            .arg(minutes, 2, 10, QLatin1Char('0'))
            .arg(seconds, 2, 10, QLatin1Char('0'));
}



GPlayer::GPlayer(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::GPlayer)
{
    m_vPalyMode.append(QString::fromLocal8Bit("列表循环"));
    m_vPalyMode.append(QString::fromLocal8Bit("单曲循环"));
    m_vPalyMode.append(QString::fromLocal8Bit("随机循环"));
    m_iPlayMode = 0;

    ui->setupUi(this);

    this->setWindowFlags(Qt::Dialog);

    ui->volSlider->hide();
    ui->volSlider->setValue(50);

    ui->playSlider->setEnabled(false);

    ui->btnPlayMode->setToolTip(QString::fromLocal8Bit("点击切换播放模式"));
    ui->btnAddSong->setToolTip(QString::fromLocal8Bit("添加歌曲"));
    ui->btnPlay->setToolTip(QString::fromLocal8Bit("播放"));
    ui->btnNext->setToolTip(QString::fromLocal8Bit("下一曲"));
    ui->btnPrevious->setToolTip(QString::fromLocal8Bit("上一曲"));
    ui->btnSetVol->setToolTip(QString::fromLocal8Bit("调节音量"));

    ui->btnPlayMode->setText(m_vPalyMode[m_iPlayMode]);

    m_music  = new QMediaPlayer(this);
    m_playlist = new QMediaPlaylist(this);

    m_playlist->setPlaybackMode(QMediaPlaylist::Loop);
    m_music->setVolume(50);

    initTrayMenu();
    initConnect();
}

void GPlayer::initTrayMenu()
{
    m_pSystemTray = new QSystemTrayIcon(this);
    if (NULL != m_pSystemTray)
    {
        m_pSystemTray->setIcon(QIcon(":/res/icon.ico"));
        m_pSystemTray->setToolTip("GPlayer");

        m_pTrayMenu = new QMenu(this);
        m_pTrayMenu->setStyleSheet("QMenu::item {padding-left:2px;}");
        QAction* actionShowWindow = new QAction(QString::fromLocal8Bit("显示主界面"), m_pTrayMenu);
        QAction* actionExit = new QAction(QString::fromLocal8Bit("退出"), m_pTrayMenu);
        m_pTrayMenu->addAction(actionShowWindow);
        m_pTrayMenu->addAction(actionExit);
        m_pSystemTray->setContextMenu(m_pTrayMenu);

        m_pSystemTray->show();

        connect(actionShowWindow, &QAction::triggered, this, [=](){
            if(this->isHidden())
            {
                this->show();
            }
            else
            {
                this->activateWindow();
            }
        });

        connect(actionExit, &QAction::triggered, this, [=](){
            exit(0);
        });
    }
}

void GPlayer::initConnect()
{
    connect(ui->btnPlayMode, &QPushButton::clicked, this, &GPlayer::clickPalyMode);
    connect(ui->btnAddSong, &QPushButton::clicked, this, &GPlayer::clickAddSong);
    connect(ui->btnSetVol, &QPushButton::clicked, this, &GPlayer::clickSetVol);
    connect(ui->btnPlay, &QPushButton::clicked, this, &GPlayer::clickPlay);
    connect(ui->btnPrevious, &QPushButton::clicked, this, &GPlayer::clickPrevious);
    connect(ui->btnNext, &QPushButton::clicked, this, &GPlayer::clickNext);

    connect(ui->actionAddFile, &QAction::triggered, this, &GPlayer::clickAddSong);
    connect(ui->actionExit, &QAction::triggered, this, [=](){
        exit(0);
    });
    connect(ui->actionOption, &QAction::triggered, this, &GPlayer::showOption);
    connect(ui->actionMute, &QAction::triggered, this, [=]{
        ui->volSlider->setValue(0);
    });
    connect(ui->actionAbout, &QAction::triggered, this, &GPlayer::showAbout);

    connect(ui->listWidget, &QListWidget::itemDoubleClicked, this, &GPlayer::clickDoubleListItem);
    connect(ui->listWidget, &QListWidget::customContextMenuRequested, this, &GPlayer::customContextMenuRequestedList);

    connect(m_playlist, &QMediaPlaylist::currentIndexChanged, this, &GPlayer::updateCurrentIndex);

    connect(m_music, &QMediaPlayer::positionChanged, this, &GPlayer::updatePosition);
    connect(m_music, &QMediaPlayer::durationChanged, this, &GPlayer::updateDuration);

    connect(ui->volSlider, &QSlider::valueChanged, m_music, &QMediaPlayer::setVolume);
    connect(ui->playSlider, &QSlider::sliderMoved, m_music, &QMediaPlayer::setPosition);
}

GPlayer::~GPlayer()
{
    delete ui;
}

void GPlayer::closeEvent(QCloseEvent *event)
{
    QMessageBox *pCloseMsgBox = new QMessageBox(this);
    QPushButton *pOkBtn = new QPushButton(QString::fromLocal8Bit("确定"), pCloseMsgBox);
    QPushButton *pQuitBtn = new QPushButton(QString::fromLocal8Bit("退出"), pCloseMsgBox);
    QPushButton *pCancelBtn = new QPushButton(QString::fromLocal8Bit("取消"), pCloseMsgBox);

    pCloseMsgBox->setIcon(QMessageBox::Warning);
    pCloseMsgBox->setWindowTitle(QString::fromLocal8Bit("提示"));
    pCloseMsgBox->setText(QString::fromLocal8Bit("是否隐藏至托盘最小化以退出程序，或点击退出关闭程序？"));

    pCloseMsgBox->addButton(pOkBtn, QMessageBox::AcceptRole);
    pCloseMsgBox->addButton(pQuitBtn, QMessageBox::AcceptRole);
    pCloseMsgBox->addButton(pCancelBtn, QMessageBox::RejectRole);

    //pCloseMsgBox->setAttribute(Qt::WA_DeleteOnClose);
    pCloseMsgBox->exec();

    if (pCloseMsgBox->clickedButton() == pOkBtn)
    {
        event->ignore();
        this->hide();
    }
    else if (pCloseMsgBox->clickedButton() == pQuitBtn)
    {
        event->accept();
    }
    else
    {
        event->ignore();
        pCloseMsgBox->close();
    }


    pCloseMsgBox->deleteLater();
}

void GPlayer::mousePressEvent(QMouseEvent *event)
{
    ui->volSlider->hide();
}

void GPlayer::clickDoubleListItem(QListWidgetItem *item)
{
    QWidget* pwig = ui->listWidget->itemWidget(item);

    if (pwig != NULL)
    {
        int id = ui->listWidget->row(item);
        m_playlist->setCurrentIndex(id);
        ui->listWidget->scrollToItem(ui->listWidget->item(id));

        QLabel * labelName =  pwig->findChild<QLabel *>("textName");
        ui->textSongName->setText(labelName->text());

        m_music->play();

        sleep(500);

        QLabel * labelDuration =  pwig->findChild<QLabel *>("textDuration");
        labelDuration->setText(Time(m_music->duration()));
        labelDuration->adjustSize();

        ui->btnPlay->setText(QString::fromLocal8Bit("暂停"));
    }
}

void GPlayer::customContextMenuRequestedList(const QPoint &pos)
{
    QListWidgetItem* curItem = ui->listWidget->itemAt( pos );
    QWidget* pwig = ui->listWidget->itemWidget(curItem);

    QMenu *popMenu = new QMenu(ui->listWidget);
    popMenu->setStyleSheet("QMenu::item {padding-left:2px; font-size:15px;}");
    QAction *actionPlay = new QAction(QString::fromLocal8Bit(" 播放 "), popMenu);
    QAction *actionDelete = new QAction(QString::fromLocal8Bit(" 删除 "), popMenu);
    QAction *actionInfo = new QAction(QString::fromLocal8Bit(" 信息 "), popMenu);
    popMenu->addAction(actionPlay);
    popMenu->addAction(actionDelete);
    popMenu->addAction(actionInfo);

    connect(actionPlay, &QAction::triggered, this, [=](){
        int id = ui->listWidget->row(curItem);
        m_playlist->setCurrentIndex(id);
        ui->listWidget->scrollToItem(ui->listWidget->item(id));

        QLabel * labelName =  pwig->findChild<QLabel *>("textName");
        ui->textSongName->setText(labelName->text());

        m_music->play();

        sleep(500);

        QLabel * labelDuration =  pwig->findChild<QLabel *>("textDuration");
        labelDuration->setText(Time(m_music->duration()));
        labelDuration->adjustSize();

        ui->btnPlay->setText(QString::fromLocal8Bit("暂停"));
    });

    connect(actionDelete, &QAction::triggered, this, [=](){
        int id = ui->listWidget->row(curItem);
        ui->listWidget->takeItem(id);
        m_playlist->removeMedia(id);
        m_music->setPlaylist(m_playlist);
    });

    connect(actionInfo, &QAction::triggered, this, [=](){
        QString info = QString::fromLocal8Bit("歌曲名 : ") + pwig->findChild<QLabel *>("textName")->text();
        info += "  \n";
        info += QString::fromLocal8Bit("文件路径 : ") + pwig->findChild<QLabel *>("textPath")->text();
        info += "  \n";
        info += QString::fromLocal8Bit("时长 : ") + pwig->findChild<QLabel *>("textDuration")->text();
        info += "  \n";
        info += QString::fromLocal8Bit("文件大小 : ") + pwig->findChild<QLabel *>("textSize")->text();
        info += " byte  \n";

        QMessageBox::about(this, QString::fromLocal8Bit("歌曲信息"), info);
    });

    popMenu->exec(QCursor::pos());

    popMenu->deleteLater();
}

void GPlayer::clickAddSong()
{
    QFileDialog *fileDialog = new QFileDialog(this);

    fileDialog->setWindowTitle(QString::fromLocal8Bit("请选择音乐文件"));

    QStringList filters;
    filters << "music(*.mp3)"
            << "all(*.*)";
    fileDialog->setNameFilters(filters);

    fileDialog->setFileMode(QFileDialog::ExistingFiles);

    if (fileDialog->exec() == QDialog::Accepted)
    {
        QStringList strPathList = fileDialog->selectedFiles();

        if(!strPathList.isEmpty())
        {
            for(int i=0; i<strPathList.size(); i++)
            {
                QString path=QDir::toNativeSeparators(strPathList.at(i));

                QFileInfo info(path);
                if (!info.exists())
                {
                    continue;
                }

                SongInfo *songWidget = new SongInfo(ui->listWidget);
                songWidget->m_textName->setText(info.fileName());
                songWidget->m_textPath->setText(path);
                songWidget->m_textSize->setText(QString::number(info.size()));

                QListWidgetItem *item = new QListWidgetItem();
                item->setToolTip(info.fileName());

                ui->listWidget->insertItem(ui->listWidget->count(), item);
                ui->listWidget->setItemWidget(item, songWidget);

                m_playlist->addMedia(QUrl::fromLocalFile(path));
            }

            m_music->setPlaylist(m_playlist);
        }
    }

    fileDialog->deleteLater();
}

void GPlayer::clickPalyMode()
{
    m_iPlayMode++;
    if(m_iPlayMode >= 3)
        m_iPlayMode = 0;

    ui->btnPlayMode->setText(m_vPalyMode[m_iPlayMode]);

    switch (m_iPlayMode) {
    case 0:
        m_playlist->setPlaybackMode(QMediaPlaylist::Loop);
        break;
    case 1:
        m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
        break;
    case 2:
        m_playlist->setPlaybackMode(QMediaPlaylist::Random);
        break;
    }
}

void GPlayer::clickSetVol()
{
    if(ui->volSlider->isHidden())
        ui->volSlider->show();
    else
        ui->volSlider->hide();
}

void GPlayer::clickPlay()
{
    if (m_music->state() == QMediaPlayer::StoppedState)
    {
        if (!m_playlist->isEmpty())
        {
            m_playlist->setCurrentIndex(0);
            m_music->play();

            sleep(500);

            QListWidgetItem* curItem = ui->listWidget->item(0);
            QWidget* pwig = ui->listWidget->itemWidget(curItem);

            QLabel * labelName =  pwig->findChild<QLabel *>("textName");
            ui->textSongName->setText(labelName->text());

            QLabel * labelDuration =  pwig->findChild<QLabel *>("textDuration");
            labelDuration->setText(Time(m_music->duration()));
            labelDuration->adjustSize();

            ui->btnPlay->setText(QString::fromLocal8Bit("暂停"));
        }
    }
    else if (m_music->state() == QMediaPlayer::PlayingState)
    {
        m_music->pause();

        ui->btnPlay->setText(QString::fromLocal8Bit("播放"));
    }
    else if (m_music->state() == QMediaPlayer::PausedState)
    {
        m_music->play();

        ui->btnPlay->setText(QString::fromLocal8Bit("暂停"));
    }
}

void GPlayer::clickPrevious()
{
    int index = m_playlist->previousIndex();

    m_playlist->setCurrentIndex(index);
    m_music->play();

    sleep(500);

    QListWidgetItem* curItem = ui->listWidget->item(index);
    QWidget* pwig = ui->listWidget->itemWidget(curItem);

    QLabel * labelName =  pwig->findChild<QLabel *>("textName");
    ui->textSongName->setText(labelName->text());

    QLabel * labelDuration =  pwig->findChild<QLabel *>("textDuration");
    labelDuration->setText(Time(m_music->duration()));
    labelDuration->adjustSize();

    ui->btnPlay->setText(QString::fromLocal8Bit("暂停"));
}

void GPlayer::clickNext()
{
    int index = m_playlist->nextIndex();

    m_playlist->setCurrentIndex(index);
    m_music->play();

    sleep(500);

    QListWidgetItem* curItem = ui->listWidget->item(index);
    QWidget* pwig = ui->listWidget->itemWidget(curItem);

    QLabel * labelName =  pwig->findChild<QLabel *>("textName");
    ui->textSongName->setText(labelName->text());

    QLabel * labelDuration =  pwig->findChild<QLabel *>("textDuration");
    labelDuration->setText(Time(m_music->duration()));
    labelDuration->adjustSize();

    ui->btnPlay->setText(QString::fromLocal8Bit("暂停"));
}

void GPlayer::showOption()
{
    Option *op = new Option();
    op->exec();
    op->deleteLater();
}

void GPlayer::showAbout()
{
    QMessageBox::about(this, QString::fromLocal8Bit("关于"), QString::fromLocal8Bit(
                                         "名称 : GPlayer                         \n"
                                         "作者 : Grow                          \n"
                                         "介绍 : GPlayer 是个界面简洁,处于实验阶段的播放器,\n"
                                         "主要依赖 Qt5 功能进行实现，可以满足日常音乐需求。\n"));

}


void GPlayer::updatePosition(qint64 position)
{
    ui->playSlider->setValue(position);
    ui->textTime->setText(Time(position)+"/"+Time(m_music->duration()));
}

void GPlayer::updateDuration(qint64 duration)
{
    ui->playSlider->setRange(0,duration);
    ui->playSlider->setEnabled(duration>0);
    ui->playSlider->setPageStep(duration/10);
}

void GPlayer::updateCurrentIndex(int index)
{
//    if(m_playlist->playbackMode() == QMediaPlaylist::Loop || m_playlist->playbackMode() == QMediaPlaylist::Random)
//    {
//        if(index == 0)
//        {
//            ui->btnPrevious->setEnabled(false);
//        }
//        else
//        {
//            ui->btnPrevious->setEnabled(true);
//        }

//        if(index == m_playlist->mediaCount() - 1)
//        {
//            ui->btnNext->setEnabled(false);
//        }
//        else
//        {
//            ui->btnNext->setEnabled(true);
//        }
//    }

    if(ui->listWidget->count() > index)
    {
        QListWidgetItem* curItem = ui->listWidget->item(index);
        QWidget* pwig = ui->listWidget->itemWidget(curItem);

        QLabel * labelName =  pwig->findChild<QLabel *>("textName");
        ui->textSongName->setText(labelName->text());
    }
}


